package math;

public class vec2i
{
    
    public static final vec2i ZERO = new vec2i();
    public static final vec2i ONE = new vec2i(1);
    
    
    public int x;
    
    public int y;
    
    
    public vec2i()
    {
        this.set(0, 0);
    }
    
    public vec2i(int aXY)
    {
        this.set(aXY, aXY);
    }
    
    public vec2i(double aXY)
    {
        this.set(aXY, aXY);
    }
    
    public vec2i(
            int aX, 
            int aY)
    {
        this.set(aX, aY);
    }
    
    public vec2i(
            double aX, 
            double aY)
    {
        this.set(aX, aY);
    }
    
    public vec2i(vec2 aOther)
    {
        this.set(aOther);
    }
    
    
    public final void set(
            int aX, 
            int aY)
    {
        this.x = aX;
        this.y = aY;
    }
    
    public final void set(int aXY)
    {
        this.set(aXY, aXY);
    }
    
    public final void set(double aXY)
    {
        this.set((int) aXY);
    }
    
    public final void set(
            double aX, 
            double aY)
    {
        this.set((int) aX, (int) aY);
    }
    
    public final void set(vec2i aOther)
    {
        this.set(aOther.x, aOther.y);
    }
    
    public final void set(vec2 aOther)
    {
        this.set((int) aOther.x, (int) aOther.y);
    }
    
    
    public void add(vec2i aTransl)
    {
        this.x += aTransl.x;
        this.y += aTransl.y;
    }
    
    public void add(int aTransl)
    {
        this.x += aTransl;
        this.y += aTransl;
    }
    
    public void sub(vec2i aTransl)
    {
        this.x -= aTransl.x;
        this.y -= aTransl.y;
    }
    
    public void sub(int aTransl)
    {
        this.x -= aTransl;
        this.y -= aTransl;
    }
    
    public void mul(vec2i aScale)
    {
        this.x *= aScale.x;
        this.y *= aScale.y;
    }
    
    public void mul(int aScale)
    {
        this.x *= aScale;
        this.y *= aScale;
    }
    
    public void div(vec2i aScale)
    {
        this.x /= aScale.x;
        this.y /= aScale.y;
    }
    
    public void div(int aScale)
    {
        this.x /= aScale;
        this.y /= aScale;
    }
    
    public void pow(vec2i aExp)
    {
        this.x = math.powi(this.x, aExp.x);
        this.y = math.powi(this.y, aExp.y);
    }
    
    public void pow(int aExp)
    {
        this.x = math.powi(this.x, aExp);
        this.y = math.powi(this.y, aExp);
    }
    
    public void abs()
    {
        this.x = math.absi(this.x);
        this.y = math.absi(this.y);
    }
    
    public void clamp(vec2i aBoundsLo, vec2i aBoundsHi)
    {
        this.x = math.clampi(this.x, aBoundsLo.x, aBoundsHi.x);
        this.y = math.clampi(this.y, aBoundsLo.y, aBoundsHi.y);
    }
    
    public void clamp(int aBoundsLo, int aBoundsHi)
    {
        this.x = math.clampi(this.x, aBoundsLo, aBoundsHi);
        this.y = math.clampi(this.y, aBoundsLo, aBoundsHi);
    }
    
    
    public boolean equals(Object aOther)
    {
        if (!(aOther instanceof vec2i))
        {
            return false;
        }
        return this.close((vec2i) aOther, 0);
    }
    
    public boolean close(vec2i aOther, int aError)
    {
        return (
            math.abs(this.x - aOther.x) < aError && 
            math.abs(this.y - aOther.y) < aError
        );
    }
    
    public boolean lessAll(vec2i aOther)
    {
        return (
            this.x < aOther.x && 
            this.y < aOther.y
        );
    }
    
    public boolean lessAny(vec2i aOther)
    {
        return (
            this.x < aOther.x || 
            this.y < aOther.y
        );
    }
    
    public boolean lequalAll(vec2i aOther)
    {
        return (
            this.x <= aOther.x && 
            this.y <= aOther.y
        );
    }
    
    public boolean lequalAny(vec2i aOther)
    {
        return (
            this.x <= aOther.x || 
            this.y <= aOther.y
        );
    }
    
    public boolean greaterAll(vec2i aOther)
    {
        return (
            this.x > aOther.x && 
            this.y > aOther.y
        );
    }
    
    public boolean greaterAny(vec2i aOther)
    {
        return (
            this.x > aOther.x || 
            this.y > aOther.y
        );
    }
    
    public boolean gequalAll(vec2i aOther)
    {
        return (
            this.x >= aOther.x && 
            this.y >= aOther.y
        );
    }
    
    public boolean gequalAny(vec2i aOther)
    {
        return (
            this.x >= aOther.x || 
            this.y >= aOther.y
        );
    }
    
    
    public int hashCode()
    {
        return (
            this.x * 33 + 
            this.y * 17 + 
            77
        );
    }
    
    
    public vec2i copy()
    {
        vec2i copy = new vec2i();
        copy.set(this);
        return copy;
    }
    
    
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        sb.append("( ");
        sb.append(this.x);
        sb.append(", ");
        sb.append(this.y);
        sb.append(" )");
        return sb.toString();
    }
    
    
    
    public static vec2i add(vec2i aA, vec2i aB)
    {
        vec2i add = aA.copy();
        add.add(aB);
        return add;
    }
    
    public static vec2i add(vec2i aA, int aB)
    {
        vec2i add = aA.copy();
        add.add(aB);
        return add;
    }
    
    public static vec2i add(int aA, vec2i aB)
    {
        vec2i add = new vec2i(aA);
        add.add(aB);
        return add;
    }
    
    public static vec2i add(int aA, int aB)
    {
        int add = aA + aB;
        return new vec2i(add);
    }
    
    public static vec2i sub(vec2i aA, vec2i aB)
    {
        vec2i sub = aA.copy();
        sub.sub(aB);
        return sub;
    }
    
    public static vec2i sub(vec2i aA, int aB)
    {
        vec2i sub = aA.copy();
        sub.sub(aB);
        return sub;
    }
    
    public static vec2i sub(int aA, vec2i aB)
    {
        vec2i sub = new vec2i(aA);
        sub.sub(aB);
        return sub;
    }
    
    public static vec2i sub(int aA, int aB)
    {
        int sub = aA - aB;
        return new vec2i(sub);
    }
    
    public static vec2i mul(vec2i aA, vec2i aB)
    {
        vec2i mul = aA.copy();
        mul.mul(aB);
        return mul;
    }
    
    public static vec2i mul(vec2i aA, int aB)
    {
        vec2i mul = aA.copy();
        mul.mul(aB);
        return mul;
    }
    
    public static vec2i mul(int aA, vec2i aB)
    {
        vec2i mul = new vec2i(aA);
        mul.mul(aB);
        return mul;
    }
    
    public static vec2i mul(int aA, int aB)
    {
        int mul = aA * aB;
        return new vec2i(mul);
    }
    
    public static vec2i div(vec2i aA, vec2i aB)
    {
        vec2i div = aA.copy();
        div.div(aB);
        return div;
    }
    
    public static vec2i div(vec2i aA, int aB)
    {
        vec2i div = aA.copy();
        div.div(aB);
        return div;
    }
    
    public static vec2i div(int aA, vec2i aB)
    {
        vec2i div = new vec2i(aA);
        div.div(aB);
        return div;
    }
    
    public static vec2i div(int aA, int aB)
    {
        int div = aA / aB;
        return new vec2i(div);
    }
    
    public static vec2i pow(vec2i aVec, vec2i aExp)
    {
        vec2i pow = aVec.copy();
        pow.pow(aExp);
        return pow;
    }
    
    public static vec2i pow(vec2i aVec, int aExp)
    {
        vec2i pow = aVec.copy();
        pow.pow(aExp);
        return pow;
    }
    
    public static vec2i abs(vec2i aVec)
    {
        vec2i abs = aVec.copy();
        abs.abs();
        return abs;
    }
    
    public static vec2i clamp(vec2i aVec, vec2i aBoundsLo, vec2i aBoundsHi)
    {
        vec2i clamp = aVec.copy();
        clamp.clamp(aBoundsLo, aBoundsHi);
        return clamp;
    }
    
    public static vec2i clamp(vec2i aVec, int aBoundsLo, int aBoundsHi)
    {
        vec2i clamp = aVec.copy();
        clamp.clamp(aBoundsLo, aBoundsHi);
        return clamp;
    }
    
    
    
}
